package com.emotion.recognition.server.mlp;

import java.util.Collections;
import java.util.List;
import java.util.Random;

import com.emotion.recognition.shared.Emotion;
import com.google.common.collect.Lists;
import com.google.gwt.rpc.server.Pair;

/**
 * For testing MLP neural network.
 * 
 * @author Minsang
 */
public class MlpTest {

    static final int INPUTS = 400;

    public static void main(String[] args) {

        MLP net = MLP.builder().setInputLayer(INPUTS, -1.0d).addHiddenLayer(4, -1.0d)
                .setOutputLayer(4)
                .setLearningRate(0.02).setMomentumRate(0.9).setMaxEpochs(2000)
                .setDesiredMaxError(0.2).buildClassifier();

        // try a set of input values

        List<List<Double>> train = MlpTestData.getTestInput();
        List<List<Double>> train_targets = MlpTestData.getTestTargets();

        List<List<Double>> test = MlpTestData.getTestTests();
        List<List<Double>> test_targets = MlpTestData.getTestTestTargets();

        double mse = net.train(train, train_targets);
        System.out.println("MSE : " + mse);

        System.out.println("SMILE SAD CALM ASTON");
        for (List<Double> t : Lists.reverse(test)) {
            filter(net.sim(t));
        }
        System.out.println("Answers:");
        for (List<Double> t : Lists.reverse(test_targets)) {
            filter(t);
        }
    }

    private static List<Double> createHugeList(double d) {
        List<Double> list = Lists.newArrayList();
        for (int i = 0; i < INPUTS; i++) {
            list.add(d);
        }
        return Collections.unmodifiableList(list);
    }

    private static void filter(List<Double> inputs) {
        for (double d : inputs) {
            System.out.printf("%.3f\t", d);
        }
        System.out.println();
    }

    private static Pair<List<List<Double>>, List<List<Double>>> createSampleData() {
        List<List<Double>> inputs = Lists.newArrayList();
        List<List<Double>> targets = Lists.newArrayList();

        Random r = new Random(1234L);

        for (int i = 0; i < 25; i++) {
            double d1 = r.nextDouble();
            Emotion target;

            if (d1 > 0.75) {
                target = Emotion.ASTONISHED; // 0001
            } else if (d1 > 0.50) {
                target = Emotion.CALM; // 0010
            } else if (d1 > 0.25) {
                target = Emotion.SAD; // 0100
            } else {
                target = Emotion.SMILING; // 1000
            }

            if (target != Emotion.NONE) {
                inputs.add(createHugeList(d1));
                targets.add(target.getOneHotEncoded());

                // System.out.println(String.format("%f %f %f %f = %s %s", d1, d2, d3, d4,
                // target.toString(), target.getOneHotEncoded().toString()));

            }
        }

        return new Pair<List<List<Double>>, List<List<Double>>>(inputs, targets);
    }

}
